
package neteasefilters.filters;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;

public class CvLinearDOF implements IImageFilter {

    // 条形虚化

    int posX, posY;
    double size;
    double angle;

    // 参数说明：posX,posY,是虚化中心点的位置（坐标）。size是虚化的范围大小（比例，0-1之间，angle是虚化条的倾斜角，0-180之间）。

    public CvLinearDOF(int _x, int _y, double _ang, double _size) {
        posX = _x;
        posY = _y;
        angle = _ang;
        size = _size;
    }

    private int _BOUND(int x, int _min, int _max) {
        if (_min <= x && x <= _max)
            return x;
        else if (x < _min)
            return _min;
        else
            return _max;
    }

    public Image Get_Line_Mask(int w, int h, double size, float centerX, float centerY, double angle) {
        centerX = centerX * w;
        centerY = centerY * h;
        int startX, startY, endX, endY;
        size = size * (w > h ? h : w);

        if (angle == 90) {
            startX = endX = (int)centerX;
            startY = _BOUND((int)(centerY - size), 0, h);
            endY = _BOUND((int)(centerY + size), 0, h);
        } else if (angle == 0) {
            startY = endY = (int)centerY;
            startX = _BOUND((int)(centerX - size), 0, w);
            endX = _BOUND((int)(centerX + size), 0, w);
        } else {
            startX = _BOUND((int)(centerX - size * Math.sin(angle * Math.PI / 180)), 0, w);
            startY = _BOUND((int)(centerY + size * Math.cos(angle * Math.PI / 180)), 0, h);
            endX = _BOUND((int)(centerX + size * Math.sin(angle * Math.PI / 180)), 0, w);
            endY = _BOUND((int)(centerY - size * Math.cos(angle * Math.PI / 180)), 0, h);
        }

        int[] _color = new int[4];
        _color[0] = Color.BLACK;
        _color[1] = Color.WHITE;
        _color[2] = Color.WHITE;
        _color[3] = Color.BLACK;

        float[] _pos = new float[4];
        _pos[0] = 0;
        _pos[1] = 0.25f;
        _pos[2] = 0.75f;
        _pos[3] = 1.0f;

        LinearGradient grad = new LinearGradient(startX, startY, endX, endY, _color, _pos,
                Shader.TileMode.CLAMP);
        Paint p = new Paint();
        p.setDither(true);
        p.setShader(grad);

        Bitmap bitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);
        Canvas c = new Canvas(bitmap);
        c.drawRect(0, 0, w, h, p);

        Image _out = new Image(bitmap);
        _out.updateColorArray();

        return _out;
    }

    @Override
    public Image process(Image imageIn) {
        int w = imageIn.getWidth();
        int h = imageIn.getHeight();

        if (posX < 0 || posY < 0 || posX > w || posY > h)
            return imageIn;

        if (size < 0 || size > 1.0)
            return imageIn;

        if (angle < 0 || angle > 180)
            return imageIn;

        float cx = (float)posX / w;
        float cy = (float)posY / h;

        Image _mask;
        _mask = Get_Line_Mask(w, h, size, cx, cy, angle);

        imageIn.updateColorArray();
        int[] _inpix = imageIn.getColorArray();
        int[] _maskpix = _mask.getColorArray();

        LibCvFilter.AddByMask(_inpix, _maskpix, w, h);
        imageIn.setColorArray(_inpix);
        System.gc();

        return imageIn;
    }
}
